#include <stdint.h>
#include <string.h>

#include "main.h"
#include "spi.h"
#include "dma.h"

#include "fx_power.h"
#include "fx_gpio.h"
#include "fx_spi.h"

#include "aoaoutil.h"
#include "rtthread.h"

#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))

// extern void fx_two_fix(SPI_HandleTypeDef *hspix);

extern void fx_base_loop(void);

void log_array(uint8_t *data, uint16_t len)
{
    rt_kprintf("[");
    for (uint16_t i = 0; i < len; i++)
    {
        rt_kprintf("0x%02X", data[i]);
        if (i != len - 1)
        {
            rt_kprintf(", ");
        }
    }
    rt_kprintf("]");
}

void fx_start(void)
{
    static uint32_t write_data[10] = {
        0x00003FC6, 0x08108022, 0x00000000, 0x0800BFD8, 0xb8010626,
        0x0910802a, 0x00000514, 0x0a00863a, 0x00000000, 0x08008526,
    };
    static uint32_t read_data[ARRAY_LEN(write_data)] = {0};

    for (uint8_t i = 0; i < ARRAY_LEN(write_data); i++)
    {
        fx_spi_tr(write_data + i, read_data + i);
        if (i != (ARRAY_LEN(write_data) - 1))
        {
            rt_thread_mdelay(1);
        }
    }
}

void fx_device_info(void)
{
    rt_kprintf("%s start\n", __FUNCTION__);

    static uint8_t device_info_write[132] = {0};
    static uint8_t device_info_read[132] = {0};

    device_info_write[0] = 0xFF;
    device_info_write[1] = 0xFF;
    device_info_write[sizeof(device_info_write) - 1] = 0x5A;

    HAL_SPI_TransmitReceive_DMA(&hspi1, device_info_write, device_info_read, sizeof(device_info_write));
    while (HAL_SPI_GetState(&hspi1) == HAL_SPI_STATE_BUSY_TX_RX)
    {
        ;
    }

    for (size_t i = 0; i < 132; i++)
    {
        if (device_info_read[i] >= 0x20 && device_info_read[i] <= 0x7E)
        {
            rt_kprintf("%c", (char)device_info_read[i]);
            // rt_kprintf("%s\n", (char *)(device_info_read + i));
            // i += rt_strlen((char *)(device_info_read + i));
        }
        else
        {
            rt_kprintf(" ");
        }
    }
    rt_kprintf("\n");

    // log_array(device_info_read, 132);
    // rt_kprintf("\n");

    rt_thread_mdelay(4);

    rt_memset(device_info_write, 0, sizeof(device_info_write));
    device_info_write[0] = 0xFF;
    device_info_write[sizeof(device_info_write) - 1] = 0x5A;
    HAL_SPI_TransmitReceive_DMA(&hspi1, device_info_write, device_info_read, sizeof(device_info_write));
    while (HAL_SPI_GetState(&hspi1) == HAL_SPI_STATE_BUSY_TX_RX)
    {
        ;
    }

    for (size_t i = 0; i < 132; i++)
    {
        if (device_info_read[i] >= 0x20 && device_info_read[i] <= 0x7E)
        {
            rt_kprintf("%c", (char)device_info_read[i]);
            // rt_kprintf("%s\n", (char *)(device_info_read + i));
            // i += rt_strlen((char *)(device_info_read + i));
        }
        else
        {
            rt_kprintf(" ");
        }
    }
    rt_kprintf("\n");

    // log_array(device_info_read, 132);
    // rt_kprintf("\n");

    rt_kprintf("%s end\n", __FUNCTION__);
}

void fx_start_aperture1(void)
{
    static uint32_t write_data[] = {
        0x00000820, 0x0B10803A, 0x00000000, 0x08008832, 0x00000C30, 0x0C108002, 0x00000000, 0x08008C02,
    };
    static uint32_t read_data[ARRAY_LEN(write_data)] = {0};

    for (uint8_t i = 0; i < ARRAY_LEN(write_data); i++)
    {
        fx_spi_tr(write_data + i, read_data + i);
        if (i != (ARRAY_LEN(write_data) - 1))
        {
            rt_thread_mdelay(1);
        }
    }
}

void fx_start_aperture2(void)
{
    static uint32_t write_data[] = {
        0x00000820, 0x0D10800A, 0x00000000, 0x08008832, 0x00000C30, 0x0E108012, 0x00000000, 0x08008C02,
    };
    static uint32_t read_data[ARRAY_LEN(write_data)] = {0};

    for (uint8_t i = 0; i < ARRAY_LEN(write_data); i++)
    {
        fx_spi_tr(write_data + i, read_data + i);
        if (i != (ARRAY_LEN(write_data) - 1))
        {
            rt_thread_mdelay(1);
        }
    }
}

int msh_device_info(int argc, void **argv)
{
    static uint32_t write_data[] = {
        0x00003FC6, 0x08108022, 0x00000000, 0x0800BFD8, 0xB8010626,
        0x0910802A, 0x00000514, 0x0A00863A, 0x00000000, 0x08008526,
    };
    static uint32_t read_data[ARRAY_LEN(write_data)] = {0};

    for (uint8_t i = 0; i < ARRAY_LEN(write_data); i++)
    {
        fx_spi_tr(write_data + i, read_data + i);
        if (i != (ARRAY_LEN(write_data) - 1))
        {
            rt_thread_mdelay(5);
        }
    }

    log_wrdata(write_data, read_data, ARRAY_LEN(write_data));
    rt_kprintf("\n");

    rt_thread_mdelay(500);

    if (read_data[6] == 0xB8010626)
    {
        static uint8_t device_info_send_buffer[131] = {0};
        static uint8_t device_info_recv_buffer[131] = {0};

        fx_spi_tr_byte(device_info_send_buffer, device_info_recv_buffer, 131);

        rt_kprintf("device_info1: ");
        for (size_t i = 0; i < 131; i++)
        {
            rt_kprintf("%02X, ", device_info_recv_buffer[i]);
        }
        rt_kprintf("\n");

        fx_spi_tr_byte(device_info_send_buffer, device_info_recv_buffer, 131);

        rt_kprintf("device_info2: ");
        for (size_t i = 0; i < 131; i++)
        {
            rt_kprintf("%02X, ", device_info_recv_buffer[i]);
        }
        rt_kprintf("\n");
    }
    // rt_thread_mdelay(500);

    return 0;
}
MSH_CMD_EXPORT_ALIAS(msh_device_info, device_info, );

int msh_bloop(int argc, void **argv)
{
    for (size_t i = 0; i < 3; i++)
    {
        static uint32_t write_data[] = {
            0x00000820,
            0x0D10800A,
            0x00000000,
            0x08008832,
        };
        // 0x000009E8, 0x0E108012, 0x00000000, 0x08008C02,
        static uint32_t read_data[ARRAY_LEN(write_data)] = {0};

        for (uint8_t i = 0; i < ARRAY_LEN(write_data); i++)
        {
            fx_spi_tr(write_data + i, read_data + i);
            if (i != (ARRAY_LEN(write_data) - 1))
            {
                rt_thread_mdelay(1);
            }
        }

        log_wrdata(write_data, read_data, ARRAY_LEN(write_data));
        rt_kprintf("\n");

        rt_thread_mdelay(1000);
    }

    return 0;
}
MSH_CMD_EXPORT_ALIAS(msh_bloop, bloop, );

int main(void)
{
    // static size_t count = 0;

    fx_used_gpio_hiz();

    // while (1)
    // {
    //     rt_thread_mdelay(1000);
    // }

    // fx_power_3v3_init();
    // fx_power_5v0_init();

    // fx_power_3v3_disable();
    // fx_power_5v0_disable();

    // rt_thread_mdelay(2000);

    // fx_gpio_init();

    // rt_thread_mdelay(1);

    // fx_power_3v3_enable();
    // fx_power_5v0_enable();

    // rt_thread_mdelay(30);

    // HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, 0);

    // rt_thread_mdelay(80);

    // HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, 1);

    fx_spi_init();

    // rt_thread_mdelay(80);

    // fx_start(); // 固定时序

    // rt_thread_mdelay(3);

    // fx_device_info();

    // rt_thread_mdelay(3);

    // fx_start_aperture1(); // 指令固定

    // rt_thread_mdelay(40);

    // fx_start_aperture2(); // 指令时序

    // // fx_two_fix(&hspi1);

    // rt_thread_mdelay(36);

    // rt_thread_mdelay(1000);

    // fx_start_test();

    while (1)
    {
        rt_thread_mdelay(1);
        // fx_base_loop();
        // fx_test();
    }

    rt_thread_mdelay(500);

    fx_power_3v3_disable();
    fx_power_5v0_disable();

    fx_used_gpio_hiz();

    fx_used_gpio_input();

    while (1)
    {
        // rt_kprintf("Hello! count: %d\n", count++);
        // fx_start(&hspi1);
        rt_thread_mdelay(1000);
    }
}
